﻿namespace Cellfish.Toolbox.Facts.Linq
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using Cellfish.Test;
    using Cellfish.Toolbox.Linq;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class TapExtensionsFacts
    {
        [TestMethod]
        public void Given_null_enumerable_When_tapping_Then_ArgumentNullException_is_thrown()
        {
            IEnumerable<int> enumeration = null;
            Ensure.Throws<ArgumentNullException>(() => enumeration.Tap(_ => { }));
        }

        [TestMethod]
        public void Given_enumerable_When_tapping_with_null_action_Then_ArgumentNullException_is_thrown()
        {
            IEnumerable<int> source = new int[0];
            Ensure.Throws<ArgumentNullException>(() => source.Tap((Action<int>)null));
        }

        [TestMethod]
        public void Given_enumerable_When_tapping_Then_no_action_is_taken_before_enumerating()
        {
            IEnumerable<int> source = new int[2];
            bool actionTaken = false;
            source.Tap(_ => { actionTaken = true; });
            Assert.IsFalse(actionTaken);
        }

        [TestMethod]
        public void Given_enumerable_When_tapping_Then_action_is_taken_while_enumerating()
        {
            IEnumerable<int> source = new int[2];
            bool actionTaken = false;
            source.Tap(_ => { actionTaken = true; }).ToArray();
            Assert.IsTrue(actionTaken);
        }

        [TestMethod]
        public void Given_enumerable_When_tapping_Then_tapped_result_is_same_as_source()
        {
            var expected = new[] { 4711, 42, 69 };
            var actual = expected.Tap(_ => { }).ToArray();
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Given_enumerable_When_tapping_Then_action_is_executed_for_each_item()
        {
            var expected = new[] { 4711, 42, 69 };
            var actual = new List<int>();
            expected.Tap(actual.Add).ToArray();
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Given_enumerable_When_tapping_with_index_action_Then_each_action_gets_index_starting_from_zero()
        {
            var expected = new[] { 4711, 42, 69 };
            var actual = new List<int>();
            expected.Tap((_, idx) => actual.Add(idx)).ToArray();
            CollectionAssert.AreEqual(new[] { 0, 1, 2 }, actual);
        }
    }
}
